home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_casm / snip9611.zip / PALNFILT.C < prev    next >
C/C++ Source or Header  |  1996-11-24  |  3KB  |  121 lines

  1. /* +++Date last modified: 17-Nov-1996 */
  2.  
  3. /*
  4. **  PALNFILT.C - A palindrome filter.
  5. **
  6. **  Reads lines of text and only passes lines which are palindromes, i.e.
  7. **  those which read the same forwards or backwards. Includes options switches
  8. **  to ignore case and/or punctuation, e.g.
  9. **
  10. **  Input               Output      w/ -C       w/ -P       w/ -C -P
  11. **  ---------------     ----------  ----------  ----------  ---------------
  12. **  toot                toot        toot        toot        toot
  13. **  Toot                            Toot                    Toot
  14. **  toot!                                       toot!       toot!
  15. **  Madam, I'm Adam                                         Madam, I'm Adam
  16. **  This is a test.
  17. **  -----------------------------------------------------------------------
  18. **
  19. **  public domain demo by Bob Stout
  20. **
  21. **  Uses GETOPTS.C and CANT.C, also from SNIPPETS
  22. */
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <ctype.h>
  27. #include "getopts.h"
  28. #include "snipfile.h"                     /* For cant()           */
  29.  
  30. #define LAST_CHAR(s) (((char *)s)[strlen(s) - 1])
  31. #define NUL '\0'
  32.  
  33. void usage(int exitval);
  34. char *rmpunc(char *str);
  35.  
  36. Boolean_T fold = False_, punc = False_, help = False_;
  37.  
  38. struct Option_Tag options[] = {
  39.       {'c', False_, Boolean_Tag, &fold, NULL, NULL, NULL},
  40.       {'p', False_, Boolean_Tag, &punc, NULL, NULL, NULL},
  41.       {'h', False_, Boolean_Tag, &help, NULL, NULL, NULL},
  42.       { 0 , False_, Error_Tag  , NULL,  NULL, NULL, NULL}
  43. };
  44.  
  45. /*
  46. **  Implemented as a true filer, defaulting to stdin and stdout.
  47. */
  48.  
  49. main(int argc, char *argv[])
  50. {
  51.       FILE *infile = stdin, *outfile = stdout;
  52.       char line[2][256];                        /* Nice & roomy   */
  53.  
  54.       if (Error_ == getopts(argc, argv))
  55.             usage(-1);
  56.       if (help)
  57.             usage(0);
  58.       if (1 < xargc)
  59.             infile = cant(xargv[1], "r");
  60.       if (2 < xargc)
  61.             outfile = cant(xargv[2], "w");
  62.       while (NULL != fgets(line[0], 255, infile))
  63.       {
  64.             char *p1, *p2;
  65.             int OK;
  66.  
  67.             strcpy(line[1], line[0]);
  68.             if ('\n' == LAST_CHAR(line[1]))
  69.                   LAST_CHAR(line[1]) = NUL;
  70.             if (fold)
  71.                   strupr(line[1]);
  72.             if (punc)
  73.                   rmpunc(line[1]);
  74.             for (p1 = line[1], p2 = &LAST_CHAR(line[1]), OK = 1;
  75.                   p2 > p1; ++p1, --p2)
  76.             {
  77.                   if (*p1 != *p2)
  78.                   {
  79.                         OK = 0;
  80.                         break;
  81.                   }
  82.             }
  83.             if (OK)
  84.                   fputs(line[0], outfile);
  85.       }
  86.       return 0;
  87. }
  88.  
  89. /*
  90. **  Tell 'em how it works
  91. */
  92.  
  93. void usage(int exitval)
  94. {
  95.       puts("Usage: PALNFILT [-cph] [infile] [outfile]");
  96.       puts("where: h = Provide help (this display)");
  97.       puts("       c = Ignore case");
  98.       puts("       p = Ignore punctuation");
  99.       puts("       infile defaults to stdin");
  100.       puts("       outfile defaults to stdout");
  101.       puts("notes: switches may not be concatenated but may be any case");
  102.       exit(exitval);
  103. }
  104.  
  105. /*
  106. **  Remove all punctuation from a string
  107. */
  108.  
  109. char *rmpunc(char *str)
  110. {
  111.       char *obuf, *nbuf;
  112.  
  113.       for (obuf = str, nbuf = str; *obuf && obuf; ++obuf)
  114.       {
  115.             if (isalpha(*obuf))
  116.                   *nbuf++ = *obuf;
  117.       }
  118.       *nbuf = NUL;
  119.       return str;
  120. }
  121.